// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
using Npgsql;

namespace SnapObjects.Data.PostgreSql
{
    public class PostgreSqlAdoDbDataVisitor : AdoDbDataVisitor
    {
        private bool _isDisposed = false;

        public PostgreSqlAdoDbDataVisitor(
            NpgsqlCommand npgsqlCommand,
            NpgsqlDataReader sqlDataReader,
            IEnumerable<IAdoDbParameter> parameters,
            IDataContextOptions contextOptions)
            : base(npgsqlCommand, sqlDataReader, parameters, contextOptions)
        {
        }

        public override void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;

            if (_reader != null)
            {
                if (!_reader.IsClosed)
                {
                    _reader.Close();

                    this.SetValueForOutputParameters();
                }

                _reader.Dispose();
            }

            if (_command != null)
            {
                if (_command.Connection.State != ConnectionState.Closed)
                {
                    _command.Cancel();
                    _command.Dispose();
                }
            }
        }

        public override async Task DisposeAsync()
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;

            if (_reader != null)
            {
                if (!_reader.IsClosed)
                {
                    await _reader.CloseAsync();

                    this.SetValueForOutputParameters();
                }

                await _reader.DisposeAsync();
            }

            if (_command != null)
            {
                if (_command.Connection.State != ConnectionState.Closed)
                {
                    _command.Cancel();

                    await _command.DisposeAsync();
                }
            }
        }
    }
}
